package edu.hit.crawler.http;

import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.apache.log4j.Logger;
import edu.hit.crawler.io.FetchOutput;
import edu.hit.crawler.io.Response;
import edu.hit.crawler.util.URLCanonicalizer;
import edu.hit.crawler.util.URLFilter;

public class HttpUtil {

	private static Logger logger = Logger.getLogger(HttpUtil.class);

	public static void main(String[] args) throws IOException {
		FetchOutput fetchout = null;
		try {
			fetchout = HttpUtil
					.getFetchOutput("http://www.chinataiwan.org/");
		} catch (HttpException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		FileOutputStream fs = new FileOutputStream("test");
		fs.write(fetchout.getContent());
		fs.close();

	}

	public static FetchOutput getFetchOutput(String url) throws HttpException,
			IOException, ParseException {

		RawDownloader d = null;

		URL u = new URL(url);
		d = new RawDownloader();
		Response response = d.Download(u); // make a request

		int code = response.getCode();
		String date = response.getHeader("Date");
		long lastModifyTime = 0;
		if (null == date) {
			lastModifyTime = 0;
		} else {
			lastModifyTime = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z",
					Locale.ENGLISH).parse(date).getTime();
		}
		byte[] content = response.getContent();

		if (code == 200) { // got a good response
			return new FetchOutput(url, lastModifyTime, content); // return it

		} else if (code == 410) { // page is gone
			return new FetchOutput(url, FetchOutput.GONE, content);

		} else if (code >= 300 && code < 400) { // handle redirect

			String location = response.getHeader("Location");
			// some broken servers, such as MS IIS, use lowercase header
			// name...
			if (location == null)
				location = response.getHeader("location");
			if (location == null)
				location = "";

			
			u = new URL(u, location);
			url = u.toString();
			logger.info(url + " redirect to " + location);
			if (!URLFilter.filter(url)) {
				logger.info(url + " isn't a legal url!");
				throw new HttpException(url + " isn't a legal url!");
			}
			url = URLCanonicalizer.getCanonicalURL(url);

			response = d.Download(new URL(url));
			code = response.getCode();
			date = response.getHeader("Date");
			if (null == date) {
				lastModifyTime = 0;
			} else {
				lastModifyTime = new SimpleDateFormat(
						"EEE, d MMM yyyy HH:mm:ss z", Locale.ENGLISH).parse(
						date).getTime();
			}

			content = response.getContent();

			if (code == 200) {
				return new FetchOutput(url, lastModifyTime, content);
			} else if (code == 400) { // bad request, mark as GONE
				logger.info("400 Bad request: " + u);
				return new FetchOutput(url, FetchOutput.GONE, content);
			} else {
				logger.info("4xx error: notfound: " + u);
				return new FetchOutput(url, FetchOutput.NOTFOUND, content);
			}

		} else if (code == 400) { // bad request, mark as GONE
			logger.info("400 Bad request: " + u);
			return new FetchOutput(url, FetchOutput.GONE, content);
		} else {
			logger.info("4xx error: notfound: " + u);
			return new FetchOutput(url, FetchOutput.NOTFOUND, content);
		}

	}
}
